import * as THREE from 'three';
import { PhysicsWorld } from '../utils/PhysicsWorld';
import { PlayerTank } from './PlayerTank';
import { Projectile } from './Projectile';
import { Explosion } from './Explosion';
import { Debug } from '../utils/Debug';

export class EnemyTank {
  // Three.js 相关
  private scene: THREE.Scene;
  private tankBody: THREE.Object3D;
  private tankTurret: THREE.Object3D;
  private tankBarrel: THREE.Object3D;
  
  // 位置和旋转
  private position: THREE.Vector3;
  private rotation: number = 0;
  private turretRotation: number = 0;
  
  // 物理和碰撞
  private physics: PhysicsWorld;
  private tankCollider: any; // 物理系统碰撞体
  
  // AI 相关
  private target: PlayerTank | null = null;
  private state: 'patrolling' | 'chasing' | 'attacking' = 'patrolling';
  private patrolDirection: THREE.Vector3;
  private patrolTimer: number = 0;
  private patrolDuration: number = 3.0; // 巡逻方向变化的时间间隔
  private detectionRange: number = 20.0; // 玩家检测范围
  private attackRange: number = 15.0; // 攻击范围
  
  // 移动属性
  private moveSpeed: number = 3.0;
  private rotationSpeed: number = 1.5;
  private turretRotationSpeed: number = 2.0;
  
  // 射击属性
  private lastShotTime: number = 0;
  private reloadTime: number = 1.5; // 秒
  private projectileSpeed: number = 20;
  private projectileDamage: number = 10;
  
  // 敌人属性
  private health: number = 50;
  private maxHealth: number = 50;
  private type: 'light' | 'medium' | 'heavy' = 'light';
  private active: boolean = true;
  
  // 坦克颜色
  private tankColor: number = 0xaa3333;
  
  // 投射物回调
  private onProjectileCreated: (projectile: Projectile) => void;
  private onDestroyed?: () => void;
  
  constructor(
    scene: THREE.Scene,
    physics: PhysicsWorld,
    loadingManager: THREE.LoadingManager,
    position: THREE.Vector3,
    onProjectileCreated: (projectile: Projectile) => void,
    onDestroyed?: () => void
  ) {
    this.scene = scene;
    this.physics = physics;
    
    // 确保position是一个有效的THREE.Vector3对象
    if (!(position instanceof THREE.Vector3)) {
      Debug.error('敌人坦克初始位置必须是THREE.Vector3类型');
      position = new THREE.Vector3(0, 0.5, 0);
    }
    
    this.position = position.clone();
    this.onProjectileCreated = onProjectileCreated;
    this.onDestroyed = onDestroyed;
    
    // 随机选择坦克类型
    this.initTankType();
    
    // 创建坦克模型
    this.createTank();
    
    // 初始化巡逻方向
    this.patrolDirection = new THREE.Vector3(
      Math.random() * 2 - 1,
      0,
      Math.random() * 2 - 1
    ).normalize();
    
    Debug.log(`敌人坦克已创建, 类型: ${this.type}, 位置: (${position.x.toFixed(1)}, ${position.y.toFixed(1)}, ${position.z.toFixed(1)})`);
  }
  
  private initTankType(): void {
    const rand = Math.random();
    
    if (rand < 0.6) { // 60% 几率
      this.type = 'light';
      this.health = 40;
      this.maxHealth = 40;
      this.moveSpeed = 3.5;
      this.reloadTime = 1.5;
      this.projectileDamage = 10;
      this.tankColor = 0xaa3333;
    } else if (rand < 0.9) { // 30% 几率
      this.type = 'medium';
      this.health = 70;
      this.maxHealth = 70;
      this.moveSpeed = 2.5;
      this.reloadTime = 2.0;
      this.projectileDamage = 15;
      this.tankColor = 0x996600;
    } else { // 10% 几率
      this.type = 'heavy';
      this.health = 100;
      this.maxHealth = 100;
      this.moveSpeed = 1.8;
      this.reloadTime = 3.0;
      this.projectileDamage = 25;
      this.tankColor = 0x555555;
    }
  }
  
  private createTank(): void {
    try {
      // 创建坦克主体
      let bodyGeometry;
      
      switch (this.type) {
        case 'light':
          bodyGeometry = new THREE.BoxGeometry(1.3, 0.5, 1.8);
          break;
        case 'medium':
          bodyGeometry = new THREE.BoxGeometry(1.5, 0.6, 2.0);
          break;
        case 'heavy':
          bodyGeometry = new THREE.BoxGeometry(1.7, 0.7, 2.2);
          break;
      }
      
      const bodyMaterial = new THREE.MeshStandardMaterial({
        color: this.tankColor,
        metalness: 0.7,
        roughness: 0.3
      });
      
      this.tankBody = new THREE.Mesh(bodyGeometry, bodyMaterial);
      this.tankBody.position.copy(this.position);
      this.tankBody.castShadow = true;
      this.tankBody.receiveShadow = true;
      
      // 创建坦克炮塔
      const turretGeometry = new THREE.CylinderGeometry(0.5, 0.5, 0.4, 8);
      const turretMaterial = new THREE.MeshStandardMaterial({
        color: this.tankColor,
        metalness: 0.7,
        roughness: 0.3
      });
      
      this.tankTurret = new THREE.Mesh(turretGeometry, turretMaterial);
      this.tankTurret.position.y = 0.25 + 0.2; // 主体高度一半 + 炮塔高度一半
      this.tankTurret.castShadow = true;
      
      // 创建坦克炮管
      let barrelLength = 0;
      
      switch (this.type) {
        case 'light':
          barrelLength = 0.9;
          break;
        case 'medium':
          barrelLength = 1.1;
          break;
        case 'heavy':
          barrelLength = 1.3;
          break;
      }
      
      const barrelGeometry = new THREE.CylinderGeometry(0.08, 0.08, barrelLength, 8);
      const barrelMaterial = new THREE.MeshStandardMaterial({
        color: 0x111111,
        metalness: 0.8,
        roughness: 0.2
      });
      
      this.tankBarrel = new THREE.Mesh(barrelGeometry, barrelMaterial);
      this.tankBarrel.position.set(0, 0, barrelLength / 2);
      this.tankBarrel.rotation.x = Math.PI / 2;
      this.tankBarrel.castShadow = true;
      
      // 组装坦克
      this.tankTurret.add(this.tankBarrel);
      this.tankBody.add(this.tankTurret);
      this.scene.add(this.tankBody);
      
      // 添加物理碰撞体
      let colliderSize;
      
      switch (this.type) {
        case 'light':
          colliderSize = new THREE.Vector3(1.3, 0.5, 1.8);
          break;
        case 'medium':
          colliderSize = new THREE.Vector3(1.5, 0.6, 2.0);
          break;
        case 'heavy':
          colliderSize = new THREE.Vector3(1.7, 0.7, 2.2);
          break;
      }
      
      this.tankCollider = this.physics.addCollider(
        this.tankBody,
        colliderSize,
        this.position,
        0,
        'enemy'
      );
    } catch (error) {
      Debug.error(`创建敌人坦克模型时出错: ${error}`);
      throw error;
    }
  }
  
  /**
   * 检查坦克是否存活
   */
  public isAlive(): boolean {
    return this.active;
  }
  
  /**
   * 更新敌人坦克
   * @param deltaTime 时间增量
   * @param target 可选的目标位置
   * @returns 坦克是否仍然活跃
   */
  public update(deltaTime: number, target?: THREE.Vector3): boolean {
    if (!this.active) return false;
    
    // 基于当前状态更新AI
    if (target) {
      this.updateAI(deltaTime, target);
    } else {
      // 没有目标时，执行巡逻行为
      this.patrol(deltaTime);
    }
    
    // 更新坦克位置
    this.tankBody.position.copy(this.position);
    this.tankBody.rotation.y = this.rotation;
    this.tankTurret.rotation.y = this.turretRotation;
    
    // 更新物理碰撞体
    this.physics.updateCollider(
      this.tankCollider, 
      this.position,
      this.rotation
    );
    
    return true;
  }
  
  /**
   * 更新敌人坦克AI
   * @param deltaTime 时间增量
   * @param target 目标位置
   */
  private updateAI(deltaTime: number, target: THREE.Vector3): void {
    // 计算到目标的距离
    const distanceToTarget = this.position.distanceTo(target);
    
    // 输出调试信息，以确认AI逻辑正在工作
    Debug.log(`敌方坦克状态: ${this.state}, 到目标距离: ${distanceToTarget.toFixed(2)}`);
    
    // 进一步增大检测范围，确保AI能察觉到玩家
    this.detectionRange = 40.0; // 更大的检测范围
    this.attackRange = 25.0;    // 更大的攻击范围
    
    // 根据距离决定状态
    if (distanceToTarget > this.detectionRange) {
      // 目标超出检测范围，切换到巡逻状态
      this.state = 'patrolling';
      this.patrol(deltaTime);
      return;
    } else if (distanceToTarget > this.attackRange) {
      // 目标在检测范围内但超出攻击范围，切换到追逐状态
      this.state = 'chasing';
    } else {
      // 目标在攻击范围内，切换到攻击状态
      this.state = 'attacking';
    }
    
    // 根据状态执行不同行为
    if (this.state === 'chasing') {
      // 追逐目标
      this.chaseTarget(deltaTime, target);
    } else if (this.state === 'attacking') {
      // 攻击目标，但首先检查是否有障碍物
      if (this.canSeeTarget(target)) {
        this.attackTarget(deltaTime, target);
      } else {
        // 如果有障碍物阻挡，则尝试移动到能看到目标的位置
        this.chaseTarget(deltaTime, target);
      }
    }
  }
  
  /**
   * 检查是否可以看到目标（没有障碍物阻挡）
   * @param target 目标位置
   */
  private canSeeTarget(target: THREE.Vector3): boolean {
    // 获取从坦克到目标的方向
    const direction = new THREE.Vector3();
    direction.subVectors(target, this.position).normalize();
    
    // 创建一个射线
    const raycaster = new THREE.Raycaster(
      this.position.clone().add(new THREE.Vector3(0, 0.5, 0)), // 起始位置稍微升高
      direction,
      0,                         // 最小距离
      this.position.distanceTo(target) // 最大距离 = 到目标的距离
    );
    
    // 检查是否有障碍物
    return !this.physics.raycastObstacle(
      this.position.clone().add(new THREE.Vector3(0, 0.5, 0)),
      direction,
      this.position.distanceTo(target)
    );
  }
  
  /**
   * 巡逻行为
   * @param deltaTime 时间增量
   */
  private patrol(deltaTime: number): void {
    // 更新巡逻定时器
    this.patrolTimer += deltaTime;
    
    // 每隔一段时间改变巡逻方向
    if (this.patrolTimer >= this.patrolDuration) {
      this.patrolTimer = 0;
      
      // 随机选择新的巡逻方向
      this.patrolDirection = new THREE.Vector3(
        Math.random() * 2 - 1,
        0,
        Math.random() * 2 - 1
      ).normalize();
      
      // 将坦克旋转到新的方向
      this.rotation = Math.atan2(this.patrolDirection.x, this.patrolDirection.z);
      
      Debug.log(`敌方坦克改变巡逻方向: (${this.patrolDirection.x.toFixed(2)}, ${this.patrolDirection.z.toFixed(2)})`);
    }
    
    // 计算移动距离和新位置，增加移动速度
    const moveDistance = this.moveSpeed * deltaTime * 1.0; // 进一步增加巡逻速度
    const moveVec = this.patrolDirection.clone().multiplyScalar(moveDistance);
    const newPosition = this.position.clone().add(moveVec);
    
    // 检查碰撞
    if (!this.physics.checkCollision(newPosition, 1.0, 'enemy', Debug.isEnabled())) {
      this.position.copy(newPosition);
      // 确保坦克位置更新
      this.tankBody.position.copy(this.position);
    } else {
      // 遇到障碍物，立即改变方向
      this.patrolTimer = this.patrolDuration; // 强制在下一帧更新方向
      
      // 随机选择一个临时逃避方向
      const avoidDirection = new THREE.Vector3(
        Math.random() * 2 - 1,
        0,
        Math.random() * 2 - 1
      ).normalize();
      
      // 尝试向避障方向移动
      const avoidVec = avoidDirection.multiplyScalar(moveDistance);
      const avoidPosition = this.position.clone().add(avoidVec);
      
      if (!this.physics.checkCollision(avoidPosition, 1.0, 'enemy')) {
        this.position.copy(avoidPosition);
        this.tankBody.position.copy(this.position);
      }
    }
  }
  
  /**
   * 追逐目标
   * @param deltaTime 时间增量
   * @param target 目标位置
   */
  private chaseTarget(deltaTime: number, target: THREE.Vector3): void {
    // 输出调试信息
    Debug.log(`敌方坦克追逐目标, 目标位置: (${target.x.toFixed(2)}, ${target.z.toFixed(2)})`);
    
    // 计算方向向量
    const directionToTarget = new THREE.Vector3();
    directionToTarget.subVectors(target, this.position).normalize();
    
    // 计算理想的旋转角度
    const targetRotation = Math.atan2(directionToTarget.x, directionToTarget.z);
    
    // 平滑旋转
    const rotationDifference = targetRotation - this.rotation;
    
    // 处理角度跨越±π的情况
    let rotationChange = rotationDifference;
    if (rotationDifference > Math.PI) rotationChange -= Math.PI * 2;
    if (rotationDifference < -Math.PI) rotationChange += Math.PI * 2;
    
    // 限制旋转速度，增加旋转响应速度
    const maxRotation = this.rotationSpeed * deltaTime * 2.0; // 进一步加快旋转速度
    rotationChange = Math.max(-maxRotation, Math.min(maxRotation, rotationChange));
    
    // 应用旋转
    this.rotation += rotationChange;
    
    // 保持旋转在-π到π范围内
    if (this.rotation > Math.PI) this.rotation -= Math.PI * 2;
    if (this.rotation < -Math.PI) this.rotation += Math.PI * 2;
    
    // 更新炮塔旋转（始终朝向目标）
    this.turretRotation = targetRotation - this.rotation;
    
    // 计算移动向量和新位置，增加移动速度
    const forwardVector = new THREE.Vector3(
      Math.sin(this.rotation),
      0,
      Math.cos(this.rotation)
    );
    
    const moveDistance = this.moveSpeed * deltaTime * 1.5; // 进一步增加追逐速度
    const moveVec = forwardVector.multiplyScalar(moveDistance);
    const newPosition = this.position.clone().add(moveVec);
    
    // 检查碰撞
    if (!this.physics.checkCollision(newPosition, 1.0, 'enemy', Debug.isEnabled())) {
      this.position.copy(newPosition);
      // 确保坦克位置更新
      this.tankBody.position.copy(this.position);
    } else {
      // 尝试斜向移动，以更积极地避开障碍物
      const sideStep = 0.9; // 再次增加斜向移动的幅度
      
      // 尝试右侧移动
      const rightMoveVec = new THREE.Vector3(
        Math.sin(this.rotation + Math.PI/4) * moveDistance * sideStep,
        0,
        Math.cos(this.rotation + Math.PI/4) * moveDistance * sideStep
      );
      const rightPosition = this.position.clone().add(rightMoveVec);
      
      if (!this.physics.checkCollision(rightPosition, 1.0, 'enemy')) {
        this.position.copy(rightPosition);
        this.tankBody.position.copy(this.position);
      } else {
        // 尝试左侧移动
        const leftMoveVec = new THREE.Vector3(
          Math.sin(this.rotation - Math.PI/4) * moveDistance * sideStep,
          0,
          Math.cos(this.rotation - Math.PI/4) * moveDistance * sideStep
        );
        const leftPosition = this.position.clone().add(leftMoveVec);
        
        if (!this.physics.checkCollision(leftPosition, 1.0, 'enemy')) {
          this.position.copy(leftPosition);
          this.tankBody.position.copy(this.position);
        }
      }
    }
  }
  
  /**
   * 攻击目标
   * @param deltaTime 时间增量
   * @param target 目标位置
   */
  private attackTarget(deltaTime: number, target: THREE.Vector3): void {
    // 停止移动，炮塔朝向目标
    this.updateTurretRotation(deltaTime, target);
    
    // 尝试射击，但首先检查是否可以看到目标（没有障碍物阻挡）
    if (this.canSeeTarget(target)) {
      const currentTime = Date.now() / 1000; // 当前时间（秒）
      
      if (currentTime - this.lastShotTime > this.reloadTime) {
        // 适当的射击几率
        const shootChance = 0.7; // 提高射击几率
        
        if (Math.random() < shootChance) {
          this.fire();
          this.lastShotTime = currentTime;
        }
      }
    } else {
      // 如果有障碍物阻挡，则切换到追逐状态
      this.state = 'chasing';
    }
  }
  
  /**
   * 更新炮塔旋转以面向目标
   * @param deltaTime 时间增量
   * @param target 目标位置
   */
  private updateTurretRotation(deltaTime: number, target: THREE.Vector3): void {
    // 计算目标相对方向
    const relativePos = target.clone().sub(this.position);
    const targetTurretAngle = Math.atan2(relativePos.x, relativePos.z);
    
    // 计算相对于坦克的角度
    const relativeTurretAngle = targetTurretAngle - this.rotation;
    
    // 规范化到±π范围
    let normalizedAngle = relativeTurretAngle;
    while (normalizedAngle > Math.PI) normalizedAngle -= Math.PI * 2;
    while (normalizedAngle < -Math.PI) normalizedAngle += Math.PI * 2;
    
    // 平滑旋转炮塔
    const turretRotStep = this.turretRotationSpeed * deltaTime;
    const deltaAngle = Math.abs(normalizedAngle - this.turretRotation);
    
    if (deltaAngle > 0.05) {
      // 确定最短旋转方向
      let rotDir = 1;
      if (Math.abs((normalizedAngle + Math.PI * 2) - this.turretRotation) < deltaAngle) {
        rotDir = 1;
      } else if (Math.abs((normalizedAngle - Math.PI * 2) - this.turretRotation) < deltaAngle) {
        rotDir = -1;
      } else {
        rotDir = (normalizedAngle > this.turretRotation) ? 1 : -1;
      }
      
      this.turretRotation += rotDir * Math.min(turretRotStep, deltaAngle);
    } else {
      // 炮塔已经对准
      this.turretRotation = normalizedAngle;
    }
    
    // 规范化炮塔角度
    while (this.turretRotation > Math.PI) this.turretRotation -= Math.PI * 2;
    while (this.turretRotation < -Math.PI) this.turretRotation += Math.PI * 2;
  }
  
  private fire(): void {
    // 计算射击起始位置和方向
    const barrelTip = new THREE.Vector3(0, 0, 0.6);
    this.tankBarrel.localToWorld(barrelTip);
    
    // 计算子弹方向（与炮管对齐）
    const direction = new THREE.Vector3();
    direction.subVectors(barrelTip, this.tankTurret.getWorldPosition(new THREE.Vector3()));
    direction.normalize();
    
    // 稍微抬高炮弹的起始位置，使其更容易被看到
    barrelTip.y += 0.1;
    
    // 创建子弹，调整速度使轨迹更明显
    const projectile = new Projectile(
      this.scene,
      barrelTip,
      direction,
      'enemy',
      this.projectileDamage,
      15 // 降低速度，使轨迹更容易观察
    );
    
    // 回调通知游戏
    this.onProjectileCreated(projectile);
    
    // 射击音效和视觉效果
    this.createMuzzleFlash(barrelTip);
    
    Debug.log('敌人坦克射击');
  }
  
  private createMuzzleFlash(position: THREE.Vector3): void {
    // 创建一个临时的Group作为容器
    const flashEffects = new THREE.Group();
    this.scene.add(flashEffects);
    
    // 创建一个临时的光源模拟枪口闪光
    const light = new THREE.PointLight(0xffaa44, 3, 4);
    light.position.copy(position);
    flashEffects.add(light);
    
    // 简单的粒子效果
    const particles = new THREE.Group();
    flashEffects.add(particles);
    
    // 添加几个小球代表粒子
    for (let i = 0; i < 3; i++) {
      const geometry = new THREE.SphereGeometry(0.04, 4, 4);
      const material = new THREE.MeshBasicMaterial({
        color: 0xffaa44,
        transparent: true,
        opacity: 0.8
      });
      
      const particle = new THREE.Mesh(geometry, material);
      
      // 随机位置偏移
      particle.position.set(
        position.x + (Math.random() - 0.5) * 0.1,
        position.y + (Math.random() - 0.5) * 0.1,
        position.z + (Math.random() - 0.5) * 0.1
      );
      
      particles.add(particle);
    }
    
    // 短暂显示后移除并清理资源
    setTimeout(() => {
      // 清理所有子物体的资源
      while (flashEffects.children.length > 0) {
        const child = flashEffects.children[0];
        flashEffects.remove(child);
        
        // 处理光源
        if (child instanceof THREE.Light) {
          child.dispose();
        }
        
        // 处理粒子组
        if (child instanceof THREE.Group) {
          while (child.children.length > 0) {
            const particle = child.children[0];
            child.remove(particle);
            
            if (particle instanceof THREE.Mesh) {
              if (particle.geometry) {
                particle.geometry.dispose();
              }
              if (particle.material) {
                if (Array.isArray(particle.material)) {
                  particle.material.forEach(m => m.dispose());
                } else {
                  particle.material.dispose();
                }
              }
            }
          }
        }
      }
      
      // 从场景中移除整个效果组
      this.scene.remove(flashEffects);
    }, 150); // 稍微延长显示时间
  }
  
  public setTarget(target: PlayerTank): void {
    this.target = target;
  }
  
  public getPosition(): THREE.Vector3 {
    return this.position.clone();
  }
  
  public getRotation(): number {
    return this.rotation;
  }
  
  public getHealth(): number {
    return this.health;
  }
  
  public getMaxHealth(): number {
    return this.maxHealth;
  }
  
  public getType(): string {
    return this.type;
  }
  
  public takeDamage(amount: number): void {
    this.health = Math.max(0, this.health - amount);
    
    // 创建受击效果
    this.createHitEffect();
    
    Debug.log(`敌人坦克受到 ${amount} 点伤害，剩余生命值: ${this.health}`);
    
    // 检查是否死亡
    if (this.health <= 0) {
      this.explode();
      return;
    }
    
    // 如果受到攻击，切换到追击状态
    if (this.state === 'patrolling') {
      this.state = 'chasing';
    }
  }
  
  private createHitEffect(): void {
    // 闪烁坦克主体
    const originalColor = (this.tankBody as THREE.Mesh).material.color.getHex();
    (this.tankBody as THREE.Mesh).material.color.set(0xff0000);
    
    // 恢复原来的颜色
    setTimeout(() => {
      if (this.active) {
        (this.tankBody as THREE.Mesh).material.color.set(originalColor);
      }
    }, 100);
  }
  
  public explode(): void {
    // 创建爆炸效果
    new Explosion(
      this.scene,
      this.position.clone(),
      1.0 // 中型爆炸
    );
    
    // 停用坦克
    this.active = false;
    this.tankBody.visible = false;
    
    Debug.log(`敌人坦克已摧毁, 类型: ${this.type}`);
  }
  
  public dispose(): void {
    // 从场景中移除坦克
    this.scene.remove(this.tankBody);
    
    // 移除物理碰撞体
    this.physics.removeCollider(this.tankCollider);
    
    this.active = false;
    
    Debug.log('敌人坦克资源已清理');
  }
} 